package com.thundersoft.mm.phone.Wifi;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.example.yangxu0703.thundermapclient.iterface.ApkCallback;
import com.thundersoft.mm.FileTransfer;
import com.thundersoft.mm.phone.ConnectionManager;

import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class WifiP2pSocket {
    private static final int DEFAULT_LISTENER_PORT = 3333;
    private static final int DEFAULT_TRANSFER_PORT = 4444;
    public static int transferPort = DEFAULT_TRANSFER_PORT;
    public static int listenPort = DEFAULT_LISTENER_PORT;
    private static final int BUFFER_SIZE = 2048;
    public static boolean listening = false;
    private static ServerSocket serverSocket = null;
    private static final String TAG = "arlauncher_socket";
    private static Socket socket;
    private static ObjectInputStream objectInputStream;
    private static InputStream inputStream;
    private static OutputStream outputStream;
    private static ObjectOutputStream objectOutputStream;


    public static String path="/sdcard/Boohe/";

    public static void listener(){
        release();
        SocketRequestExecutor.execute(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Log.e(TAG, "监听glasses端的请求...");
                        if (listenPort > 9999){
                            listenPort = DEFAULT_LISTENER_PORT;
                        }
                        serverSocket = new ServerSocket();
                        serverSocket.setReuseAddress(true);
                        serverSocket.bind(new InetSocketAddress(listenPort));
                        listening = true;
                        socket = serverSocket.accept();
                        socket.setTcpNoDelay(true);

                        inputStream = socket.getInputStream();
                        outputStream = socket.getOutputStream();
                        objectInputStream = new ObjectInputStream(inputStream);
                        objectOutputStream = new ObjectOutputStream(outputStream);
                        while (true) {
                            try {
//
                                FileTransfer fileTransfer = (FileTransfer) objectInputStream.readObject();
                                String header = fileTransfer.getHeader();
                                if (header != null) {
                                    JSONObject jsonObject = new JSONObject(header);
                                    if (jsonObject.optInt("type",0) == 300) {
                                        // 接收到glasses的ip地址
                                        String ip = socket.getInetAddress().getHostAddress();
                                        String port = jsonObject.optString("msg","");
                                        if (port != null){
                                            transferPort = Integer.parseInt(port);
                                        }
                                        Log.e(TAG, "获取到glasses端的ip: " + ip + ",transferPort="+transferPort);
                                        ConnectionManager.mGlassesIp = ip;
                                        continue;
                                    }else if (jsonObject.optInt("type",0) == 400) {
                                        // glasses传过来的图片和video
                                        int total = jsonObject.optInt("total",0);
                                        Log.e(TAG, "glasses传过来的图片和video 总数: " + total);
                                    }
                                }
                                Log.e(TAG, "待接收的文件: " + fileTransfer.getFilePath());
                                String name = new File(fileTransfer.getFilePath()).getName();
                                File dir = new File(path);
                                if (!dir.exists()){
                                    dir.mkdir();
                                }
                                File file = new File(dir ,name);
                                if (file.exists()){
                                    file.delete();
                                }
                                FileOutputStream fileOutputStream = new FileOutputStream(file);
                                int bufLen = BUFFER_SIZE;
                                byte buf[] = new byte[bufLen];
                                int len;
                                long total = 0;
                                int progress = 0;
                                while ((len = inputStream.read(buf)) != -1) {
                                    fileOutputStream.write(buf, 0, len);
                                    total += len;
                                    int p = (int) ((total * 100) / fileTransfer.getFileLength());

                                    int remainLen = (int) (fileTransfer.getFileLength() - total);
                                    if (p != progress){
                                        progress = p;
                                        Log.e(TAG, "文件接收进度: " + progress +" , remainLen="+remainLen);
                                        if (progress==100){
                                            Log.i(TAG,"文件接收完毕！");
                                        }
                                    }
                                    if (total == fileTransfer.getFileLength()) {
                                        break;
                                    }

                                    if (remainLen < bufLen){
                                        Log.i(TAG,"文件接收进入最后阶段..........！");
                                        byte buffer[] = new byte[remainLen];
                                        Log.i(TAG,"文件接收进入最后阶段，即将阻塞接收数据..........！");
                                        inputStream.read(buffer);
                                        Log.i(TAG,"文件接收最后阶段接收数据完毕......文件接收最后阶段接收数据完毕....！");
                                        fileOutputStream.write(buffer, 0, remainLen);
                                        Log.i(TAG,"文件接收成功..........！");
                                        break;
                                    }
                                }
                                fileOutputStream.flush();
                                fileOutputStream.close();
                            }catch (Exception e){
                                if (socket == null || socket.isClosed()){
                                    release();
//                                    listener();
                                    break;
                                }
                                try {
                                    socket.close();
                                    Thread.sleep(1000);
                                }catch (Exception ee){}
                                e.printStackTrace();
                            }
                        }
                    }catch (Exception e){
                        Log.i("arlauncher","listener error "+e.getLocalizedMessage());
                        listenPort ++;
                        release();
                    }
                }

            }
        });
    }

    private static class TransferType{
        FileTransfer fileTransfer;
        String ip;
        ApkCallback apkCallback;
    }
    static boolean transfering = false;
    static List<TransferType> mTransferTypeList = new ArrayList<>();

    public synchronized  static void transfer(final FileTransfer fileTransfer, final String ip, final ApkCallback apkCallback){
        if (transfering){
            TransferType transferType = new TransferType();
            transferType.fileTransfer = fileTransfer;
            transferType.ip = ip;
            transferType.apkCallback = apkCallback;
            mTransferTypeList.add(transferType);
            return;
        }
        transfering = true;
        SocketRequestExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    objectOutputStream.writeObject(fileTransfer);
                    File file = new File(fileTransfer.getFilePath());
                    FileInputStream inputStream = new FileInputStream(file);
                    long fileSize = fileTransfer.getFileLength();
                    long total = 0;
                    byte buf[] = new byte[BUFFER_SIZE];
                    int len;
                    int p = 0;
                    while ((len = inputStream.read(buf)) != -1) {
                        outputStream.write(buf, 0, len);
                        total += len;
                        int progress = (int) ((total * 100) / fileSize);
                        if (p != progress) {
                            p = progress;
                            Log.e(TAG, "Progress = "+progress + ", " +
                                    "fileSize="+fileSize + " ,transferPort="+transferPort + ", ip="+ip);
                            if (apkCallback != null)
                                apkCallback.fallBackProgress(progress);
                        }
                    }
                    Log.e(TAG, "文件发送成功");
                    transfering = false;
                    if (!mTransferTypeList.isEmpty()){
                        TransferType transferType = mTransferTypeList.remove(0);
                        transfer(transferType.fileTransfer,transferType.ip,transferType.apkCallback);
                    }
                } catch (Exception ee) {
                    transfering = false;
                    ee.printStackTrace();
                    if (socket == null || socket.isClosed()){
                        release();
                        listener();
                    }
                    if (apkCallback!=null){
                        apkCallback.fallBackProgress(-1);
                    }
                    Log.e(TAG, "文件发送异常 Exception: " + ee.getLocalizedMessage());
                } finally {
                }
            }
        });
    }

    public static void release(){
        listening = false;
        try {
            if (objectInputStream != null){
                objectInputStream.close();
            }

        }catch (Exception e){

        }finally {
            objectInputStream = null;
        }
        try {
            if (inputStream != null){
                inputStream.close();
            }
        }catch (Exception e){

        }finally {
            inputStream = null;
        }
        try {
            if (socket != null){
                socket.close();
            }
        }catch (Exception e){

        }finally {
            socket = null;
        }
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}
